﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;


namespace Teal.Compiler {

    /// <summary>
    /// 提供语义解析使用的辅助函数。
    /// </summary>
    public static partial class ResolveHelper {

        #region 访问权限

        /// <summary>
        /// 判断在指定成员上下文是否可以访问指定的成员引用。
        /// </summary>
        /// <param name="memberDefinition">当前成员定义。</param>
        /// <param name="member">要判断的成员引用。</param>
        /// <returns></returns>
        public static bool canAccess(MemberDefinition memberDefinition, MemberReference member) {

            switch (member.modifiers & (Modifiers.@protected | Modifiers.@private)) {

                // public: 全部可以访问。
                case Modifiers.none:
                    return true;

                // private: 同项目内可访问。
                case Modifiers.@private:

                    // 导入的私有成员无法访问。
                    if (member.definition == null) {
                        return false;
                    }

                    // 当前项目内全局私有成员可以访问。
                    if (member.container.memberType == MemberType.@namespace) {
                        return true;
                    }

                    // 内嵌成员，则只有相同容器可以访问。
                    return memberDefinition.reference.isNestedChildOf(member.container);

                // protected: 同命名空间可访问。
                default:
                    return canAccessProtected(memberDefinition, member);

            }

        }

        /// <summary>
        /// 判断在指定成员上下文是否可以访问指定的属性访问器。
        /// </summary>
        /// <param name="memberDefinition">当前成员定义。</param>
        /// <param name="member">要判断的成员引用。</param>
        /// <param name="modifiers">访问器的访问权限。</param>
        /// <returns></returns>
        public static bool canAccessProperyAccessor(MemberDefinition memberDefinition, MemberReference member, Modifiers modifiers) {
            switch (modifiers) {
                case Modifiers.@public:
                    return true;
                case Modifiers.@private:
                    return memberDefinition.reference.isNestedChildOf(member.container);
                case Modifiers.@protected:
                    return canAccessProtected(memberDefinition, member);
                default:
                    throw new Unreachable();
            }
        }

        /// <summary>
        /// 判断在指定成员上下文是否可以访问指定的保护的成员引用。
        /// </summary>
        /// <param name="memberDefinition">当前成员定义。</param>
        /// <param name="member">要判断的成员引用。</param>
        /// <returns></returns>
        public static bool canAccessProtected(MemberDefinition memberDefinition, MemberReference member) {

            // 全局保护成员，只有本项目或者属于相同命名空间才能访问。
            if (member.container.memberType == MemberType.@namespace) {
                return member.definition != null || memberDefinition.reference.isNestedChildOf(member.container);
            }

            // 只要当前成员及外部成员有一个是指定的容器类型的基类，可以访问。
            var parentType = member.containerType;
            var c = memberDefinition.reference;
            do {
                var ct = c as TypeReference;
                if (ct != null && parentType.isAssignableTypeFrom(ct)) {
                    return true;
                }
            } while ((c = c.container) != null);
            return false;
        }

        /// <summary>
        /// 判断在当前上下文是否可以通过指定的实例访问保护成员。
        /// </summary>
        /// <param name="memberDefinition">当前成员定义。</param>
        /// <param name="instance">调用成员使用的实例。</param>
        /// <returns></returns>
        public static bool canAccessProtected(MemberDefinition memberDefinition, Expression instance) {

            // 调用基类的保护成员时，其限定类型必须是当前类型或子类型。

            // 如果当前成员不存在父类型，则必然无法调用 protected 成员。
            var parentType = memberDefinition.reference.containerType;
            return parentType != null && parentType.isAssignableFrom(instance.resolvedType);
        }

        #endregion

        #region 成员查找

        /// <summary>
        /// 判断指定的成员是否可以和已有成员组成重载。
        /// </summary>
        /// <param name="members">已有的成员组。</param>
        /// <param name="maxCount">要检查的数目。</param>
        /// <param name="other">要检查的成员。</param>
        /// <returns></returns>
        public static bool isNewOverload(MemberReferenceGroup members, int maxCount, MemberReference other) {
            if (!other.memberType.isOverloadable()) {
                return members.Count == 0;
            }
            for (int i = 0; i < maxCount; i++) {
                if (members[i].isOverriding(other)) {
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// 获取显式接口成员名。
        /// </summary>
        /// <param name="explicitType"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static string toExplicitName(TypeReference explicitType, string name) {
            StringBuilder buffer = new StringBuilder();
            buffer.Append('@');
            explicitType.writeSignature(buffer);
            buffer.Append('.');
            buffer.Append(name);
            return buffer.ToString();
        }

        ///// <summary>
        ///// 如果指定的符号是成员组，则检查是否具有重载资格并返回一个合法符号。
        ///// </summary>
        ///// <param name="symbol"></param>
        ///// <param name="name"></param>
        ///// <param name="srcNode"></param>
        ///// <returns></returns>
        //public static ISymbol checkOverload(ISymbol symbol, string name, Node srcNode) {
        //    MemberReferenceGroup members = symbol as MemberReferenceGroup;
        //    if (members != null) {

        //        // 只有一个元素不需要使用方法组成员。
        //        if (members.Count == 1) {
        //            return members[0];
        //        }

        //        // 确认每个项都可重载。
        //        for (int i = 0; i < members.Count; i++) {
        //            if (!members[i].memberType.isOverloadable()) {
        //                Compiler.error(ErrorCode.none, String.Format("无法确定“{0}”具体指“{1}”还是“{2}”", name, members[0].fullName, members[i == 0 ? 1 : i].fullName), srcNode);
        //                return null;
        //            }
        //        }
        //    }

        //    return symbol;
        //}

        /// <summary>
        /// 向用户报告成员绑定的错误。
        /// </summary>
        /// <param name="result">绑定的结果。</param>
        /// <param name="container">查找所在的容器。如果不存在容器则为 null 。</param>
        /// <param name="memberName">要查找的名称。</param>
        /// <param name="memberUsage">当前成员的使用场景。用于报错时能优化提示。</param>
        /// <param name="srcNode">引发本次搜索的原始语法树节点。用于报错时能提示正确的位置。</param>
        public static void reportBindMemberError(MemberBindResult result, NamespaceReference container, string memberName, MemberUsage memberUsage, Node srcNode) {
            switch (result.type) {
                case MemberBindResultType.notFound:
                    switch (memberUsage) {
                        case MemberUsage.importTarget:
                            if (container != null) {
                                Compiler.error(ErrorCode.none, String.Format("“{0}”下不直接存在名称“{1}”", container.signature, memberName), srcNode);
                            } else {
                                Compiler.error(ErrorCode.none, String.Format("全局范围不存在名称“{0}”", memberName), srcNode);
                            }
                            break;
                        default:
                            if (container != null) {
                                Compiler.error(ErrorCode.none, String.Format("“{0}”下不存在名称“{1}”", container.signature, memberName), srcNode);
                            } else {
                                // 尝试定位实际的命名空间。
                                var found = ListObjectPool<MemberReference>.alloc();
                                findNamespace(Compiler.currentModule.reference, memberName, found);
                                if (found.Count > 0) {
                                    string s = null;
                                    for (int i = 0; i < found.Count; i++) {
                                        if (i > 0) {
                                            s += "或";
                                        }
                                        s += "“import " + found[i].container.signature + "”";
                                        if (i > 2) {
                                            s += "等";
                                            break;
                                        }
                                    }

                                    Compiler.error(ErrorCode.none, String.Format("当前上下文不存在名称“{0}”；请添加{1}", memberName, s), srcNode);
                                } else {
                                    Compiler.error(ErrorCode.none, String.Format("当前上下文不存在名称“{0}”；是否缺少类库引用？", memberName), srcNode);
                                }
                                ListObjectPool<MemberReference>.free(found);
                            }
                            break;
                    }
                    break;
                case MemberBindResultType.accessDenied:
                    Compiler.error(ErrorCode.none, String.Format("无法访问{0}成员“{1}”", result.found.modifiers.getAcccessibilityReadableName(), result.found.signature), srcNode);
                    break;
                case MemberBindResultType.ambiguous:
                    if (result.found.memberType == MemberType.errorType) {
                        // todo
                        Compiler.error(ErrorCode.none, String.Format("无法确定“{0}”具体指库“{2}”还是“{1}”中的“{3}”", memberName, result.found.containerModule.name, result.found.next.containerModule.name, result.found.next.signature), srcNode);
                    } else {
                        Compiler.error(ErrorCode.none, String.Format("无法确定“{0}”具体指“{2}”还是“{1}”", memberName, result.found.signature, result.alt.signature), srcNode);
                    }
                    break;
                case MemberBindResultType.genericNotMatched:
                    if (result.found.genericParameters == null) {
                        Compiler.error(ErrorCode.none, String.Format("“{0}”不是泛型，不需要使用泛型参数", result.found.signature), srcNode);
                    } else {
                        Compiler.error(ErrorCode.none, String.Format("使用泛型“{0}”需要 {1} 个泛型参数", result.found.signature, result.found.genericParameters.Length), srcNode);
                    }
                    break;
            }

        }

        /// <summary>
        /// 根据成员名检索其命名空间。
        /// </summary>
        /// <param name="memebrName"></param>
        /// <returns></returns>
        private static void findNamespace(NamespaceReference container, string name, List<MemberReference> result) {
            var member = container.getMember(name);
            if (member != null) {
                result.Add(member);
                return;
            }
            foreach (var vk in container.members) {
                if (vk.Value is NamespaceReference) {
                    findNamespace((NamespaceReference)vk.Value, name, result);
                }
            }
        }

        ///// <summary>
        ///// 向用户报告成员未找到的错误。
        ///// </summary>
        ///// <param name="memberDefinition">绑定所在的成员定义。</param>
        ///// <param name="container">查找所在的容器。</param>
        ///// <param name="memberName">要查找的名称。</param>
        ///// <param name="genericArgumentCount">泛型形参的个数。</param>
        ///// <param name="memberUsage">当前成员的使用场景。用于报错时能优化提示。</param>
        ///// <param name="srcNode">引发本次搜索的原始语法树节点。用于报错时能提示正确的位置。</param>
        //public static void reportBindSymbolError(MemberDefinition memberDefinition, MemberContainerReference container, string memberName, int genericArgumentCount, Node srcNode) {
        //    var result = new MemberBindResult();
        //    if (container != null) {
        //        memberDefinition.bindMember(container, memberName, genericArgumentCount, ref result);
        //    } else {
        //        memberDefinition.bindMember(memberName, genericArgumentCount, ref result);
        //    }
        //    if (result.type == MemberBindResultType.notFound && container == null) {
        //        Compiler.error(ErrorCode.none, String.Format("当前上下文不存在名称“{0}”", memberName), srcNode);
        //        return;
        //    }

        //    if (result.type == MemberBindResultType.success) {
        //        Compiler.error(ErrorCode.none, String.Format("无法通过类型“{2}”访问{0}成员“{1}”，应使用“{3}”或其子类", result.found.modifiers.getAcccessibilityReadableName(), result.found.fullName, container.fullName, memberDefinition.reference.parentContainer.fullName), srcNode);
        //        return;
        //    }

        //    reportBindMemberError(result, container, memberName, MemberUsage.type, srcNode);
        //}

        ///// <summary>
        ///// 检测 static 修饰符是否有效。
        ///// </summary>
        ///// <param name="member">要处理的成员引用。</param>
        ///// <param name="context">当前上下文对象。</param>
        ///// <param name="instance">要检查的实例对象。</param>
        ///// <param name="srcNode">引发本次操作的源节点，主要用于报错。如果设为 null，则不报错。</param>
        //public static void checkInstance(MemberReference member, ResolveContext context, ref Expression instance, Node srcNode) {

        //    bool isStatic = member.modifiers.hasFlag(Modifiers.@static | Modifiers.@const);

        //    // instance 为 Expression.empty 时，根据表达式自动决定是否使用实例成员。
        //    if (instance == Expression.empty) {

        //        if (isStatic) {
        //            instance = null;
        //            return;
        //        }

        //        if (context.currentMemberDefinition.reference.modifiers.hasFlag(Modifiers.@static | Modifiers.@const)) {
        //            Compiler.error(ErrorCode.none, String.Format("无法在静态或常量成员内访问非静态成员“{0}”", member.fullName), srcNode);
        //            return;
        //        }

        //        instance = new ThisLiteral() {
        //            targetType = context.currentMemberDefinition.reference.parentType
        //        };
        //        return;
        //    }

        //    if (isStatic) {
        //        if (instance != null) {
        //            Compiler.error(ErrorCode.none, String.Format("静态成员“{0}”必须通过类名直接访问", member.fullName), srcNode);
        //        }
        //    } else {
        //        if (instance == null) {
        //            Compiler.error(ErrorCode.none, String.Format("非静态成员“{0}”必须通过实例对象访问", member.fullName), srcNode);
        //        }
        //    }

        //}

        #endregion

        #region 类型

        ///// <summary>
        ///// 查找两个类型的公共基类。
        ///// </summary>
        ///// <param name="typeA">The type a.</param>
        ///// <param name="typeB">The type b.</param>
        ///// <returns></returns>
        //public static TypeReference getCommonBaseType(TypeReference typeA, TypeReference typeB) {
        //    if (typeA == null) {
        //        return typeB;
        //    }

        //    // 有一个是 dynamic,返回 dynamic
        //    if (typeA == PredefinedTypes.@dynamic || typeB == PredefinedTypes.@dynamic) {
        //        return PredefinedTypes.@dynamic;
        //    }

        //    // 有一个是 void，返回另一个。
        //    if (typeA == PredefinedTypes.@void) {
        //        return typeB;
        //    }
        //    if (typeB == PredefinedTypes.@void) {
        //        return typeA;
        //    }

        //    // 有一个是 var，返回另一个。
        //    if (typeA == PredefinedTypes.@var) {
        //        return typeB;
        //    } 
        //    if (typeB == PredefinedTypes.@var) {
        //        return typeA;
        //    }

        //    // 如果 A 可以转为 B，则使用 B。
        //    var t1tot2 = ResolveHelper.classifyImplicitConversion(null, typeA, typeB) != ConversionType.none;
        //    var t2tot1 = ResolveHelper.classifyImplicitConversion(null, typeB, typeA) != ConversionType.none;

        //    if (t1tot2 != t2tot1) {
        //        if (t1tot2) {
        //            return typeB;
        //        } else {
        //            return typeA;
        //        }
        //    }

        //    // 使用 A 和 B 的公共基类。
        //    for (var b = typeA.baseType; b != null; b = b.baseType) {
        //        if (b.isAssignableTypeFrom(typeB)) {
        //            return b;
        //        }
        //    }

        //    return PredefinedTypes.System_Object;
        //}

        /// <summary>
        /// 检查一个类型是否可作为变量类型。
        /// </summary>
        /// <param name="type">要检查的类型。</param>
        /// <param name="srcNode">引发本次操作的源节点，主要用于报错。</param>
        public static void checkVaribaleType(TypeReference type, Node srcNode) {

            switch (type.memberType) {
                case MemberType.@class:
                    if (type.modifiers.hasFlag(Modifiers.@static)) {
                        Compiler.error(ErrorCode.none, String.Format("无法创建静态类型“{0}”的变量", type.signature), srcNode);
                    }
                    break;
                case MemberType.@enum:
                case MemberType.@struct:
                case MemberType.@interface:
                case MemberType.typeParameter:
                    break;
                case MemberType.specailType:
                    if (type == PredefinedTypes.@void) {
                        Compiler.error(ErrorCode.none, "无法创建“void”类型的变量", srcNode);
                    }
                    break;
                default:
                    Compiler.error(ErrorCode.none, String.Format("“{0}”不是合法的类型", type.signature), srcNode);
                    break;
            }

        }

        /// <summary>
        /// 报告将 var 解析为 object 的警告。
        /// </summary>
        /// <param name="srcNode">引发本次操作的源节点，主要用于报错。</param>
        public static void reportVarAsDynamicError(Node srcNode) {
            if (Compiler.options.disallowVarAsObject) {
                Compiler.error(ErrorCode.none, "在当前上下文无法推断“var”所代表的类型；应改为明确的类型", srcNode);
            }
        }

        #endregion

        #region 修饰符

        /// <summary>
        /// 检查指定类型是否适用于 const 。
        /// </summary>
        /// <param name="type">当前变量的类型。</param>
        /// <param name="srcNode">引发本次操作的源节点，主要用于报错。</param>
        public static void checkConst(TypeReference type, Node srcNode) {
            //if (type.primitiveType == PrimitiveType.none && type != PredefinedTypes.System_String) {
            //    Compiler.error(ErrorCode.none, String.Format("类型“{0}”不能是常量", type.fullName), srcNode);
            //}
        }

        /// <summary>
        /// 检查指定类型是否适用于 volatile 。
        /// </summary>
        /// <param name="type">当前变量的类型。</param>
        /// <param name="srcNode">引发本次操作的源节点，主要用于报错。</param>
        public static void checkVolatile(TypeReference type, Node srcNode) {
            if (!canVolatile(type)) {
                Compiler.error(ErrorCode.none, "“volatile”对结构、double、long、ulong 无效", srcNode);
            }
        }

        private static bool canVolatile(TypeReference type) {
            //switch (type.memberType) {
            //    case MemberType.@struct:
            //        switch (type.primitiveType) {
            //            case PrimitiveType.none:
            //            case PrimitiveType.float64:
            //            case PrimitiveType.int64:
            //            case PrimitiveType.uint64:
            //                return false;
            //            default:
            //                return true;
            //        }
            //    case MemberType.@enum:
            //        return canVolatile(type.baseType.genericArguments[0]);
            //    case MemberType.@class:
            //    default:

            switch (type.BuiltinType) {
                case BuiltinTypeSpec.Type.Bool:
                case BuiltinTypeSpec.Type.Char:
                case BuiltinTypeSpec.Type.SByte:
                case BuiltinTypeSpec.Type.Byte:
                case BuiltinTypeSpec.Type.Short:
                case BuiltinTypeSpec.Type.UShort:
                case BuiltinTypeSpec.Type.Int:
                case BuiltinTypeSpec.Type.UInt:
                case BuiltinTypeSpec.Type.Float:
                case BuiltinTypeSpec.Type.UIntPtr:
                case BuiltinTypeSpec.Type.IntPtr:
                    return true;
            }

            if (TypeReference.IsReferenceType(type))
                return true;

            if (type.IsEnum)
                return true;

            return false;
            //}
        }

        /// <summary>
        /// 检查指定的成员是否已被否定。
        /// </summary>
        /// <param name="type"></param>
        /// <param name="srcNode"></param>
        public static void checkDeprecated(TypeReference type, Node srcNode) {

            //// type 可能未解析。
            //TypeDefinition d = type.memberDefinition as TypeDefinition;
            //if (d != null && d.phase < TypeResolvePhase.bodyResolved) {
            //    type.memberDefinition.parentPackage.addDeferedDeprecatedMembers(type, srcNode);
            //    return;
            //}

            //checkDeprecated((MemberReference)type, srcNode);
        }

        /// <summary>
        /// 检查指定的成员是否已被否定。
        /// </summary>
        /// <param name="member"></param>
        /// <param name="srcNode"></param>
        public static void checkDeprecated(MemberReference member, Node srcNode) {
            //var deprecatedData = (DeprecatedData)member.getPredefinedAnnotation(PredefinedTypes.System_DeprecatedAnnotation);
            //if (deprecatedData != null) {
            //    if (deprecatedData.error) {
            //        Compiler.error(ErrorCode.none, String.Format("“{0}”已被否定{1}", member.fullName, deprecatedData.message == null ? null : ("(" + deprecatedData.message + ")")), srcNode);
            //    } else {
            //        Compiler.warning(ErrorCode.none, String.Format("“{0}”已被否定{1}", member.fullName, deprecatedData.message == null ? null : ("(" + deprecatedData.message + ")")), srcNode);
            //    }
            //}
        }

        #endregion

        #region 泛型生成

        /// <summary>
        /// 填充指定的泛型定义的参数，返回新的泛型。
        /// </summary>
        /// <param name="genericDefinition">泛型定义成员引用。</param>
        /// <param name="genericArguments">泛型参数。</param>
        /// <param name="memberDefinition">要处理的成员定义。</param>
        /// <param name="memberUsage">成员的适用场景，主要用于报错。</param>
        /// <returns></returns>
        public static MemberReference makeGenericMember(MemberReference genericDefinition, List<Expression> genericArguments, MemberDefinition memberDefinition, MemberUsage memberUsage, Node srcNode) {

            // 处理泛型参数。
            bool isEmptyArguments;
            var typeArgs = resolveGenericArguments(genericArguments, memberDefinition, memberUsage, srcNode, out isEmptyArguments);
            if (typeArgs == null) {
                return null;
            }

            // 处理 typeof(A<>)，除非 memberUsage == typeof，否则空参都会报错。
            if (isEmptyArguments) {
                return genericDefinition;
            }

            // Type<T>
            var genericDefinitionType = genericDefinition as GenericTypeDefinitionReference;
            if (genericDefinitionType != null) {
                return genericDefinitionType.makeGenericType(typeArgs);
            }

            // fn<T>
            // 在解析成员时，不需要处理泛型方法。
            var genericDefinitionMethod = genericDefinition as GenericMethodDefinitionReference;
            if (genericDefinitionMethod != null) {
                return genericDefinitionMethod.makeGenericMethod(typeArgs);
            }

            throw new Unreachable();

        }

        ///// <summary>
        ///// 填充指定的泛型定义的参数，返回新的泛型。
        ///// </summary>
        ///// <param name="genericDefinition">泛型定义成员引用。</param>
        ///// <param name="genericArguments">泛型参数。</param>
        ///// <param name="memberDefinition">要处理的成员定义。</param>
        ///// <param name="memberUsage">成员的适用场景，主要用于报错。</param>
        ///// <returns></returns>
        //public static ISymbol makeGenericSymbol(ISymbol genericDefinition, List<Expression> genericArguments, ResolveContext context, SymbolUsage symbolUsage, Node srcNode) {

        //    // 此函数负责组合指定的符号和泛型实参为新的泛型。
        //    // 符号可能为：
        //    //    泛型类型定义
        //    //    泛型方法定义
        //    //    泛型方法组定义

        //    // 处理泛型参数。
        //    bool isEmptyGenericArguments;
        //    var resolvedGenericTypeArguments = resolveGenericArguments(genericArguments, context.currentMemberDefinition, MemberUsage.type, srcNode, out isEmptyGenericArguments);

        //    // Type<T>
        //    var genericDefinitionType = genericDefinition as GenericTypeDefinitionReference;
        //    if (genericDefinitionType != null) {
        //        return genericDefinitionType.makeGenericType(resolvedGenericTypeArguments, genericArguments);
        //    }

        //    // fn<T>
        //    var genericDefinitionMethod = genericDefinition as GenericMethodDefinitionReference;
        //    if (genericDefinitionMethod != null) {
        //        return genericDefinitionMethod.makeGenericMethod(resolvedGenericTypeArguments, genericArguments);
        //    }

        //    // 方法组：对所有方法进行构造，并应用泛型约束，如果无成功结果，则返回 null 。
        //    // fn<T>(int), fn<T>(bool), ...
        //    var genericDefinitionMethodGroup = genericDefinition as MemberReferenceGroup;
        //    if (genericDefinitionMethodGroup != null) {

        //        Debug.Assert(genericDefinitionMethodGroup.Count > 0);

        //        // 将方法组所有方法组合泛型，并忽略不符合泛型约束的方法。
        //        MemberReferenceGroup result = new MemberReferenceGroup(genericDefinitionMethodGroup.Count);
        //        for (int i = 0; i < genericDefinitionMethodGroup.Count; i++) {

        //            var method = genericDefinitionMethodGroup[i] as GenericMethodDefinitionReference;

        //            Debug.Assert(method != null, "返回的方法组存在非泛型方法");

        //            genericDefinitionMethodGroup[i] = method.makeGenericMethod(resolvedGenericTypeArguments);

        //        }

        //        //// 所有成员都不符合泛型约束，则报错。
        //        //if (result.Count == 0) {
        //        //    var m = genericDefinitionMethodGroup[0];
        //        //    MemberReferenceGroup.free(result);
        //        //    ResolveHelper.checkConstraints(m, resolvedGenericTypeArguments, genericArguments);
        //        //    //Compiler.error(ErrorCode.none, String.Format("至少有一个泛型实参不匹配“{0}”所有重载的泛型约束", m.parentContainer == null ? m.parentContainer.fullName + "." + m.name : m.name), srcNode);
        //        //    return null;
        //        //}

        //        //if (result.Count == 1) {
        //        //    var m = result[0];
        //        //    MemberReferenceGroup.free(result);
        //        //    return m;
        //        //}

        //        return result;
        //    }

        //    throw new Unreachable();

        //}

        /// <summary>
        /// 解析泛型参数。
        /// </summary>
        /// <param name="genericArguments"></param>
        /// <param name="memberDefinition"></param>
        /// <param name="memberUsage"></param>
        /// <returns></returns>
        private static TypeReference[] resolveGenericArguments(List<Expression> genericArguments, MemberDefinition memberDefinition, MemberUsage memberUsage, Node srcNode, out bool isEmptyGenericArguments) {

            // 找到第一个空泛型参数。
            int firstNullIndex = -1;
            for (int i = 0; i < genericArguments.Count; i++) {
                if (genericArguments[i] == null) {
                    firstNullIndex = i;
                    break;
                }
            }

            if (firstNullIndex >= 0) {

                isEmptyGenericArguments = true;

                // 只有在 typeof 上下文才能使用空参数。
                if (memberUsage != MemberUsage.@typeof) {
                    Compiler.error(ErrorCode.none, String.Format("缺少第 {0} 个泛型参数", firstNullIndex + 1), srcNode);
                    return null;
                }

                // 确保所有参数都是空的。
                for (int i = firstNullIndex; i < genericArguments.Count; i++) {
                    if (genericArguments[i] != null) {
                        Compiler.error(ErrorCode.none, "在未提供泛型实参时，必须省略所有泛型实参", genericArguments[i]);
                    }
                }

                return null;
            }

            // 全部参数都已提供。
            isEmptyGenericArguments = false;

            var resolvedGenericTypeArguments = new TypeReference[genericArguments.Count];

            bool hasError = false;
            for (int i = 0; i < resolvedGenericTypeArguments.Length; i++) {
                var resolvedGenericTypeArgument = resolvedGenericTypeArguments[i] = genericArguments[i].resolveAsType(memberDefinition, memberUsage);
                if (resolvedGenericTypeArgument == null) {
                    hasError = true;
                    continue;
                }

                if (resolvedGenericTypeArgument.memberType != MemberType.specailType) {
                    checkVaribaleType(resolvedGenericTypeArgument, genericArguments[i]);
                } else if (resolvedGenericTypeArgument == PredefinedTypes.var) {
                    Compiler.error(ErrorCode.none, "无法使用“var”作为泛型实参", genericArguments[i]);
                    hasError = true;
                    continue;
                }

            }

            if (hasError) {
                return null;
            }

            return resolvedGenericTypeArguments;

        }

        #endregion

        #region 成员重写

        /// <summary>
        /// 判断子类的返回类型和父类返回类型是否是有效的重写。
        /// </summary>
        /// <param name="thisType"></param>
        /// <param name="baseType"></param>
        public static bool isOverriding(TypeReference thisType, TypeReference baseType) {
            if (thisType == baseType) {
                return true;
            }

            //
            // 对于以下情况：
            //
            //     abstract class A {
            //        public abstract T fn<T>();
            //     }
            //
            //     class B : A {
            //        public override T fn<T>() { ... }
            //     }
            //
            // A.fn<T> 和 B.fn<T> 是重写的，但两者是不同引用。
            //

            if (thisType.memberType == MemberType.typeParameter && baseType.memberType == MemberType.typeParameter) {
                var thisTypeParameter = (MemberReference.GenericParameter)thisType;
                var baseTypeParameter = (MemberReference.GenericParameter)baseType;
                return thisTypeParameter.index == baseTypeParameter.index && thisTypeParameter.containerDefinitionMember.memberType == MemberType.method && baseTypeParameter.containerDefinitionMember.memberType == MemberType.method;
            }

            // 如果两个类型来自不同的泛型定义，则不需判断。
            if (thisType.genericDefinition != baseType.genericDefinition) {
                return false;
            }

            Debug.Assert(thisType.genericArguments != null);
            Debug.Assert(baseType.genericArguments != null);
            Debug.Assert(thisType.genericArguments == baseType.genericArguments);

            do {
                for (int i = 0; i < thisType.genericArguments.Length; ++i) {
                    if (!isOverriding(thisType.genericArguments[i], baseType.genericArguments[i])) {
                        return false;
                    }
                }

                thisType = thisType.containerType;
                baseType = baseType.containerType;
            } while (thisType != null);

            return true;
        }

        /// <summary>
        /// 比较当前成员和指定成员是否具有相同的泛型约束。
        /// </summary>
        /// <param name="other"></param>
        /// <returns>返回第一个出现区别的泛型形参索引。</returns>
        public static int checkOverridingGenericTypeParameterConstraints(MemberReference thisMember, MemberReference baseMember) {
            var thisPs = thisMember.genericParameters;
            var basePs = baseMember.genericParameters;
            if (thisPs != null) {
                Debug.Assert(basePs != null);
                Debug.Assert(thisPs.Length == basePs.Length);
                for (int i = 0; i < thisPs.Length; i++) {
                    if (!checkOverridingGenericTypeParameterConstraint(thisPs[i], basePs[i])) {
                        return i;
                    }
                }
            }
            return -1;
        }

        private static bool checkOverridingGenericTypeParameterConstraint(MemberReference.GenericParameter thisParameter, MemberReference.GenericParameter baseParameter) {
            if (!isOverriding(thisParameter.baseClass, baseParameter.baseClass)) {
                return false;
            }

            var tb = thisParameter.baseInterfaces;
            var bb = baseParameter.baseInterfaces;

            if (tb == null) {
                return bb == null;
            }

            if (bb == null || tb.Count != bb.Count) {
                return false;
            }

            for (int i = 0; i < tb.Count; i++) {
                bool found = false;
                for (int j = 0; j < bb.Count; ++j) {
                    if (isOverriding(tb[i], bb[j])) {
                        found = true;
                        break;
                    }
                }

                if (!found) {
                    return false;
                }
            }

            return true;
        }

        #endregion
    }

}